package com.zhangxun.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zhangxun.doc.ProdEs;
import com.zhangxun.service.EsSearchService;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.MoreLikeThisQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

@Service
public class EsSearchServiceImpl implements EsSearchService {
    @Autowired
    private ElasticsearchRestTemplate elasticsearchRestTemplate;

    @Override
    public Page<ProdEs> prodListByTagId(Page<ProdEs> page, Long tagId) {
        //设置分页
        NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder();
        builder.withPageable(PageRequest.of((int)page.getCurrent()-1,(int)page.getSize()));

        //设置标签查询条件
        builder.withQuery(QueryBuilders.matchQuery("tagList",tagId));
        NativeSearchQuery query = builder.build();
        SearchHits<ProdEs> search = elasticsearchRestTemplate.search(query, ProdEs.class);
        //将查询的数据和总记录条数封装到page当中
        page.setTotal(search.getTotalHits());
        List<ProdEs> prodEsList = search.getSearchHits().stream()
                .map(hit -> hit.getContent()).collect(Collectors.toList());

        page.setRecords(prodEsList);

        return page;
    }

    /**
     * 关键字搜索服务
     * @param page 分页信息
     * @param prodName 关键字
     * @param sort 排序关键字。0，1，2.
     * 0表示综合排序，1表示根据价格排序，2表示根据销量排序
     * @return
     */
    @Override
    public Page<ProdEs> selectPage(Page<ProdEs> page, String prodName, Integer sort) {
        //设置分页
        NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder();
        builder.withPageable(PageRequest.of((int)page.getCurrent()-1,(int)page.getSize()));

        //设置名称和卖点为关键字的查询条件
        builder.withQuery(QueryBuilders.multiMatchQuery(prodName,"prodName","brief"));

        //排序
        builder.withSort(setSort(sort));
        //获取查询条件对象
        NativeSearchQuery query = builder.build();
        //查询es数据
        SearchHits<ProdEs> search = elasticsearchRestTemplate.search(query, ProdEs.class);

        //将数据封装到page当中
        page.setTotal(search.getTotalHits());
        List<ProdEs> prodEsList = search.get().map(searchHit -> searchHit.getContent()).collect(Collectors.toList());
        page.setRecords(prodEsList);

        return page;

    }

    /**
     * 根据排序id返回排序条件的方法
     * @param sort
     * @return
     */
    private SortBuilder setSort(Integer sort) {

        switch (sort) {
            case 0:
                return new FieldSortBuilder("positiveRating").order(SortOrder.DESC);
            case 1:
                return new FieldSortBuilder("soldNum").order(SortOrder.DESC);
            case 2:
                return new FieldSortBuilder("price").order(SortOrder.DESC);
        }
        return null;

    }




    /**
     * 根据分类id查询商品的方法，分页使用默认分页
     * @param cateGoryId 商品的分类id
     * @return
     */
    @Override
    public Page<ProdEs> searchByCategoryId(Long cateGoryId) {
        Page<ProdEs> page = new Page<>();
        NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder();
        builder.withPageable(PageRequest.of((int)page.getCurrent()-1,(int) page.getSize()));

        builder.withQuery(QueryBuilders.matchQuery("cateGoryId",cateGoryId));
        NativeSearchQuery query = builder.build();
        SearchHits<ProdEs> search = elasticsearchRestTemplate.search(query, ProdEs.class);

        page.setTotal(search.getTotalHits());
        List<ProdEs> prodEsList = search.getSearchHits().stream().map(hit -> hit.getContent()).collect(Collectors.toList());
        page.setRecords(prodEsList);
        return page;

    }

}
